const mockDatabase = require('../config/mockDatabase');
const { v4: uuidv4 } = require('uuid');
const path = require('path');
const fs = require('fs').promises;

class ReportExport {
  constructor(data) {
    this.id = data.id;
    this.export_id = data.export_id;
    this.report_key = data.report_key;
    this.admin_id = data.admin_id;
    this.export_format = data.export_format;
    this.filters = data.filters;
    this.file_name = data.file_name;
    this.file_path = data.file_path;
    this.file_size = data.file_size;
    this.status = data.status;
    this.error_message = data.error_message;
    this.download_count = data.download_count;
    this.expires_at = data.expires_at;
    this.created_at = data.created_at;
    this.updated_at = data.updated_at;
  }

  // 创建新的导出任务
  static async create(exportData) {
    try {
      if (!mockDatabase.reportExports) {
        mockDatabase.reportExports = [];
      }
      
      const exportId = uuidv4();
      const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
      const fileName = `${exportData.report_key}_${timestamp}.${exportData.export_format}`;
      
      // 设置过期时间（7天后）
      const expiresAt = new Date();
      expiresAt.setDate(expiresAt.getDate() + 7);
      
      const newExport = {
        id: mockDatabase.reportExports.length + 1,
        export_id: exportId,
        report_key: exportData.report_key,
        admin_id: exportData.admin_id,
        export_format: exportData.export_format,
        filters: exportData.filters || {},
        file_name: fileName,
        file_path: null, // 将在文件生成后设置
        file_size: null,
        status: 'pending',
        error_message: null,
        download_count: 0,
        expires_at: expiresAt.toISOString(),
        created_at: new Date().toISOString(),
        updated_at: new Date().toISOString()
      };
      
      mockDatabase.reportExports.push(newExport);
      return new ReportExport(newExport);
    } catch (error) {
      console.error('Error creating report export:', error);
      throw error;
    }
  }

  // 根据export_id获取导出记录
  static async findByExportId(exportId) {
    try {
      const exports = mockDatabase.reportExports || [];
      const exportRecord = exports.find(e => e.export_id === exportId);
      
      return exportRecord ? new ReportExport(exportRecord) : null;
    } catch (error) {
      console.error('Error finding export by ID:', error);
      throw error;
    }
  }

  // 获取用户的导出记录
  static async findByAdminId(adminId, limit = 20, offset = 0) {
    try {
      const exports = mockDatabase.reportExports || [];
      const userExports = exports
        .filter(e => e.admin_id === adminId)
        .sort((a, b) => new Date(b.created_at) - new Date(a.created_at))
        .slice(offset, offset + limit);
      
      return userExports.map(exportRecord => new ReportExport(exportRecord));
    } catch (error) {
      console.error('Error finding exports by admin ID:', error);
      throw error;
    }
  }

  // 获取报表的导出记录
  static async findByReportKey(reportKey, limit = 50) {
    try {
      const exports = mockDatabase.reportExports || [];
      const reportExports = exports
        .filter(e => e.report_key === reportKey)
        .sort((a, b) => new Date(b.created_at) - new Date(a.created_at))
        .slice(0, limit);
      
      return reportExports.map(exportRecord => new ReportExport(exportRecord));
    } catch (error) {
      console.error('Error finding exports by report key:', error);
      throw error;
    }
  }

  // 更新导出状态
  static async updateStatus(exportId, status, additionalData = {}) {
    try {
      const exports = mockDatabase.reportExports || [];
      const exportIndex = exports.findIndex(e => e.export_id === exportId);
      
      if (exportIndex === -1) {
        throw new Error('Export record not found');
      }
      
      exports[exportIndex] = {
        ...exports[exportIndex],
        status,
        ...additionalData,
        updated_at: new Date().toISOString()
      };
      
      return new ReportExport(exports[exportIndex]);
    } catch (error) {
      console.error('Error updating export status:', error);
      throw error;
    }
  }

  // 标记导出完成
  static async markCompleted(exportId, filePath, fileSize) {
    try {
      return await this.updateStatus(exportId, 'completed', {
        file_path: filePath,
        file_size: fileSize
      });
    } catch (error) {
      console.error('Error marking export completed:', error);
      throw error;
    }
  }

  // 标记导出失败
  static async markFailed(exportId, errorMessage) {
    try {
      return await this.updateStatus(exportId, 'failed', {
        error_message: errorMessage
      });
    } catch (error) {
      console.error('Error marking export failed:', error);
      throw error;
    }
  }

  // 增加下载次数
  static async incrementDownloadCount(exportId) {
    try {
      const exports = mockDatabase.reportExports || [];
      const exportIndex = exports.findIndex(e => e.export_id === exportId);
      
      if (exportIndex === -1) {
        throw new Error('Export record not found');
      }
      
      exports[exportIndex].download_count += 1;
      exports[exportIndex].updated_at = new Date().toISOString();
      
      return new ReportExport(exports[exportIndex]);
    } catch (error) {
      console.error('Error incrementing download count:', error);
      throw error;
    }
  }

  // 清理过期的导出文件
  static async cleanupExpiredExports() {
    try {
      const exports = mockDatabase.reportExports || [];
      const now = new Date();
      const expiredExports = [];
      
      for (let i = exports.length - 1; i >= 0; i--) {
        const exportRecord = exports[i];
        if (new Date(exportRecord.expires_at) < now) {
          // 删除文件
          if (exportRecord.file_path) {
            try {
              await fs.unlink(exportRecord.file_path);
            } catch (fileError) {
              console.warn('Failed to delete expired export file:', fileError.message);
            }
          }
          
          expiredExports.push(exportRecord);
          exports.splice(i, 1);
        }
      }
      
      return expiredExports.length;
    } catch (error) {
      console.error('Error cleaning up expired exports:', error);
      throw error;
    }
  }

  // 获取导出统计信息
  static async getExportStats(adminId = null, reportKey = null) {
    try {
      let exports = mockDatabase.reportExports || [];
      
      // 应用筛选条件
      if (adminId) {
        exports = exports.filter(e => e.admin_id === adminId);
      }
      
      if (reportKey) {
        exports = exports.filter(e => e.report_key === reportKey);
      }
      
      const stats = {
        total: exports.length,
        pending: exports.filter(e => e.status === 'pending').length,
        processing: exports.filter(e => e.status === 'processing').length,
        completed: exports.filter(e => e.status === 'completed').length,
        failed: exports.filter(e => e.status === 'failed').length,
        total_downloads: exports.reduce((sum, e) => sum + e.download_count, 0),
        formats: {
          csv: exports.filter(e => e.export_format === 'csv').length,
          xlsx: exports.filter(e => e.export_format === 'xlsx').length,
          pdf: exports.filter(e => e.export_format === 'pdf').length
        }
      };
      
      return stats;
    } catch (error) {
      console.error('Error getting export stats:', error);
      throw error;
    }
  }

  // 检查导出文件是否存在
  async checkFileExists() {
    try {
      if (!this.file_path) {
        return false;
      }
      
      await fs.access(this.file_path);
      return true;
    } catch (error) {
      return false;
    }
  }

  // 获取文件下载URL
  getDownloadUrl() {
    if (this.status !== 'completed' || !this.file_path) {
      return null;
    }
    
    return `/api/reports/exports/${this.export_id}/download`;
  }

  // 检查是否已过期
  isExpired() {
    return new Date() > new Date(this.expires_at);
  }

  // 验证导出数据
  static validateExportData(exportData) {
    const errors = [];
    
    if (!exportData.report_key) {
      errors.push('report_key is required');
    }
    
    if (!exportData.admin_id) {
      errors.push('admin_id is required');
    }
    
    if (!exportData.export_format || !['csv', 'xlsx', 'pdf'].includes(exportData.export_format)) {
      errors.push('Valid export_format is required');
    }
    
    return errors;
  }
}

module.exports = ReportExport;